package com.mo.config;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.TypeReference;
import org.springframework.data.redis.serializer.RedisSerializer;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

/**
 * redis fastjson2 序列化配置.
 */
@SuppressWarnings("all")
public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
    public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
    private final Class<T> clazz;

    // 构造器
    public FastJsonRedisSerializer(Class<T> clazz) {
        super();
        this.clazz = clazz;
    }

    // 序列化
    @Override
    public byte[] serialize(T value) {
        if (value == null) {
            return new byte[0];
        }
        String jsonString = JSON.toJSONString(value, JSONWriter.Feature.WriteClassName);
        return jsonString.getBytes(DEFAULT_CHARSET);
    }

    // 反序列化
    @Override
    public T deserialize(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        String jsonString = new String(bytes, DEFAULT_CHARSET);

        // 判断 jsonString 是否为数组
        if (jsonString.trim().startsWith("[") && jsonString.trim().endsWith("]")) {
            // 如果是数组，使用 parseList 解析
            return (T) parseList(jsonString);
        }

        // 不是数组的情况，处理为包含 @type 字段的对象
        if (jsonString.contains("@type")) {
            try {
                // 解析为一个单独的 JSON 对象
                JSONObject jsonObject = JSON.parseObject(jsonString);
                // 获取对象中的 @type 字段
                String className = jsonObject.getString("@type");
                // 根据 @type 字段的值选择对应的类进行反序列化
                Class<?> targetClass = Class.forName(className);

                // 如果目标类是 HashMap 类型，使用 TypeReference 进行反序列化
                if (Map.class.isAssignableFrom(targetClass)) {
                    // 获取 Map 类型的详细信息
                    TypeReference<Map<String, Object>> typeReference = new TypeReference<Map<String, Object>>() {
                    };
                    return (T) JSON.parseObject(jsonObject.toJSONString(), typeReference);
                }

                // 如果是 List 类型，使用 parseList
                if (List.class.isAssignableFrom(targetClass)) {
                    TypeReference<List<Object>> typeReference = new TypeReference<List<Object>>() {
                    };
                    return (T) JSON.parseObject(jsonObject.toJSONString(), typeReference);
                }

                // 对于其他类型的对象，直接反序列化为目标类
                return (T) JSON.parseObject(jsonObject.toJSONString(), targetClass);

            } catch (ClassNotFoundException e) {
                throw new RuntimeException("Class not found: " + e.getMessage(), e);
            }
        }

        // 默认处理为普通对象
        return JSON.parseObject(jsonString, clazz);
    }

    // 反序列化列表数据
    private T parseList(String jsonString) {
        // 解析为 List
        List<JSONObject> jsonList = JSON.parseArray(jsonString, JSONObject.class);

        // 处理每个元素
        for (JSONObject jsonObject : jsonList) {
            String className = jsonObject.getString("@type");
            // 根据 `@type` 字段的值选择对应的类进行反序列化
            try {
                Class<?> targetClass = Class.forName(className);
                // 反序列化为该类的对象
                return (T) JSON.parseObject(jsonObject.toJSONString(), targetClass);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException("Class not found: " + className, e);
            }
        }
        return null; // 如果没有找到符合条件的元素
    }
}